﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kindohm.Life.Library
{
    public class ProximityFinder
    {
        Point start;
        Board board;
        int maxRange;

        public T FindNearestItem<T>(Board board, Point start, int maxRange) where T:BoardObject
        {
            this.start = start;
            this.board = board;
            this.maxRange = maxRange;

            return this.GetItemOnPerimeter<T>(1);
        }

        protected virtual bool ObjectIsValid<T>(T item) where T:BoardObject
        {
            return true;
        }
        
        T GetItemOnPerimeter<T>(int range) where T : BoardObject
        {
            if (range > maxRange)
            {
                return null;
            }

            T item;

            //top line
            int yy = start.Y + range;
            for (int x = (start.X - range); x < (start.X + range); x++)
            {
                if (x >= 0 && x < board.Width && yy > 0 && yy < board.Height)
                {
                    item = board.BoardObjects[new Point(x, yy)] as T;
                    if (item != null && this.ObjectIsValid<T>(item))
                    {
                        return item;
                    }
                }
            }

            //bottom line
            yy = start.Y - range;
            for (int x = (start.X - range); x < (start.X + range); x++)
            {
                if (x >= 0 && x < board.Width && yy > 0 && yy < board.Height)
                {
                    item = board.BoardObjects[new Point(x, yy)] as T;
                    if (item != null && this.ObjectIsValid<T>(item))
                    {
                        return item;
                    }
                }
            }

            //left line
            int xx = start.X - range;
            for (int y = (start.Y - range) + 1; y <= (start.Y + range); y++)
            {
                if (xx >= 0 && xx < board.Width && y > 0 && y < board.Height)
                {
                    item = board.BoardObjects[new Point(xx, y)] as T;
                    if (item != null && this.ObjectIsValid<T>(item))
                    {
                        return item;
                    }
                }
            }

            //right line
            xx = start.X + range;
            for (int y = (start.Y - range); y <= (start.Y + range); y++)
            {
                if (xx >= 0 && xx < board.Width && y > 0 && y < board.Height)
                {
                    item = board.BoardObjects[new Point(xx, y)] as T;
                    if (item != null && this.ObjectIsValid<T>(item))
                    {
                        return item;
                    }
                }
            }

            return this.GetItemOnPerimeter<T>(range + 1);
        }

    }
}
